文件侠告诉你,Python复制文件的N种姿势! 您所在的位置:网站首页 py 复制文件 文件侠告诉你,Python复制文件的N种姿势!

文件侠告诉你,Python复制文件的N种姿势!

2023-09-16 21:05| 来源: 网络整理| 查看: 265

一、不太完美的开端

最近在审核一个实习生写的Python代码,其中有一个文件复制的功能,代码如下:

with open('source.txt', 'rb') as f, open('target.txt', 'wb') as g: while True: block = f.read(8*1024) # 每次复制8KB字节 if not block: # end of file break g.write(block)

其实这段代码从实现上看没有任何问题,也非常完美,不过这里有一个问题。项目使用了Python语言,而Python语言拥有强大的API后援团。对于复制文件这样的基础操作,不可能没有现成的API,难道非要写n行代码才能搞定吗?尽管代码实现没有任何问题,但有现成的API(这里指的是官方原生的API)为何不用呢?而且Python的API都是经过成千上万人验证的,出错几率很低。如果自己写代码,很可能会引入未知的bug。所以,这里对广大初学者的建议是:如果有现成API,应该尽量使用现成的API,没有必要什么都自己实现(想炫耀自己牛叉的除外)。

据我所知,在Python中,可以实现复杂文件功能的函数至少有10个,也许更多。所以在开发Python项目时,尤其是复杂的项目,了解Python中的API非常必要,不一定所有的API都会使用,但至少要知道Python到底可以实现什么功能,如果用到,再研究具体的用法不迟。这里插播一天广告:我即将推出Python API深度详解系列文章,包含了Python中几乎所有的核心API的用法,这些API是Python中的瑰宝,请大家持续关注哦!

于是我告诉这位同学,编写Python代码应尽可能使用原生API实现,要求他重新编写这段代码,于是这位同学又编写出了下面的代码:

from pathlib import Path source = Path('source.txt') destination = Path('target.txt') destination.write_bytes(source.read_bytes()) open(destination, 'wb').write(open(source, 'rb').read())

没错,你是用了新的API,但和复制文件没有直接关系啊!还有,这不还是使用了很多行代码吗!区别只是一次性读取了文件中的所有内容,换汤不换药啊!于是,我又启发这位同学,我希望用一行代码搞定,are you ok?

二、 复制文件的Python API真是太丰富了

那位同学做得怎么样,我还没有看,因为已经到周末了,趁着休息写了这篇文章,顺道总结下关于复制文件的各种Python API,希望那位同学可以在网上搜索到这篇文件,如果没搜索到,就只能自己想了!

Python中至少有3个模块提供了复制文件的函数,这3个模块是shutil、os和subprocess。其中shutil模块提供的是纯的复制文件的函数,而os和subprocess并未直接提供复制文件的函数,而是提供了执行系统命令的函数,通过系统命令可以间接复制文件,例如macOS和Linux的cp命令用于复制文件,而Windows的copy命令用于复制文件。所以如果使用os和subprocess模块中的API复制文件,就要考虑到跨平台特性了。

shutil模块中用于复制文件的主要函数如下:

copyfilecopycopy2copyfileobj

os和subprocess函数主要是一些用于执行命令的函数,如system、call等,这些在本文后面的内容中会详细介绍。

三、shutil模块,复制文件函数的集中营

shutil模块中有大量的函数可以用来复制文件,这一节将详细介绍这些函数的用法和差异。

1. copyfile函数

该函数的原型如下:

copyfile(src, dst)

copyfile函数用于复制文件内容(不包含元数据,如文件的权限)。src参数表示源文件,dst表示目标文件。dst必须是完整的目标文件名。如果src和dst是同一文件,会抛出shutil.Error异常。dst必须是可写的,否则会抛出IOError。如果dst已经存在,该文件会被替换。对于特殊文件,例如字符或块设备和管道不能使用此功能,因为copyfile会打开并阅读文件。

例子:

from shutil import copyfile # 相对路径 copyfile("test.txt", "xxxx.txt") # 绝对路径 copyfile("/file/test.txt", "/product/product.txt")

2. copy函数

该函数的原型如下:

copy(src, dst)

copy函数与copyfile函数类似,都是用于复制文件的,但与copyfile函数有如下两点区别:

(1)dst可以是文件,也可以是目录,如果是目录,则目标文件名与原文件名相同;

(2)copy函数不仅会复制文件内容,也会复制文件的权限。但并不会复制其他的状态信息,如最后访问时间,最后修改时间等;

例子:

from shutil import copy # dst是目录,会生成/product/test.txt文件 copy("test.txt", "/product") # det是文件 copy("test.txt", "/product/abcd.txt")

3. copy2函数

与copy函数的功能类似,但除了copy函数的功能外,还会复制文件的状态信息,如最后访问时间,最后修改时间等。类似Linux的cp -p命令。

例子:

from shutil import copy2 # dst是目录,会生成/product/test.txt文件 copy2("test.txt", "/product") # det是文件 copy2("test.txt", "/product/abcd.txt")

4. copymode函数

该函数并不复制文件本身,而是复制文件的访问权限,所以dst必须存在。

例子:

from shutil import copymode # /product/xyz.txt必须存在,复制后,会发现test.txt与xyz.txt文件的访问权限相同了 copy2("test.txt", "/product/xyz.txt")

5. copyfileobj函数

copyfileobj函数的两个参数src和dst并不是字符串形式的文件或目录的路径,而是打开文件的句柄,需要先使用open函数打开文件。

例子:

file_src = 'test.txt' # 打开源文件 f_src = open(file_src, 'rb') file_dest = 'okokok.txt' # 打开目标文件 f_dest = open(file_dest, 'wb') from shutil import copyfileobj # 开始复制文件 copyfileobj(f_src, f_dest)

我一口气讲了5个函数,又增加了很多奇怪的知识,不过还有更奇怪的呢!继续往下看!

四、利用系统的命令复制文件

不管是Windows、macOS,还是Linux,或是其他任何操作系统,都会提供用于复制文件的命令,例如,macOS和Linux用于复制文件的命令是cp;Windows用于复制文件的命令是copy。

如果读者不熟悉这两个命令,可以看下帮助:

执行cp --help,会得到如图1所示的帮助信息:

图1

执行copy /?命令,会得到如图2所示的帮助信息:

图2

os模块和subprocess模块都提供了丰富的函数用于执行系统命令。

例子:

# 使用os模块 import os # 在Linux、Unix或macOS下 os.system('cp src.txt dst.txt') # 在Windows下 os.system('copy src.txt dst.txt') # 使用subprocess模块 import subprocess # 在Linux、Unix或macOS下 status = subprocess.call('cp src.txt dst.txt', shell=True) # 在Windows下 status = subprocess.call('copy src.txt dst.txt', shell=True)

好了,现在我们已经介绍了Python中用于复制文件的主要函数(还有其他函数,但功能类似),感觉自己就像个文件侠,复制文件终于可以不用写这么多代码了,欧耶!

- EOF -



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有